package com.guigu.guliproduct.service.impl;

import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guigu.gulicommon.entity.dto.SelectSkuInfoPagesDto;
import com.guigu.gulicommon.entity.pojo.res.PagePoJo;
import com.guigu.gulicommon.entity.pojo.res.Res;
import com.guigu.gulicommon.entity.vo.SkuInfoPageVo;
import com.guigu.gulicommon.exception.BaseException;
import com.guigu.guliproduct.entity.SkuImages;
import com.guigu.guliproduct.entity.SkuInfo;
import com.guigu.guliproduct.entity.SpuInfoDesc;
import com.guigu.guliproduct.entity.bo.SkuItemSaleAttrBo;
import com.guigu.guliproduct.entity.bo.SpuItemAttrGroupBo;
import com.guigu.guliproduct.entity.vo.SkuInfoItemVo;
import com.guigu.guliproduct.mapper.*;
import com.guigu.guliproduct.service.ISkuInfoService;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

import static com.guigu.gulicommon.constant.enumes.res.SelectResCode.SELECT_PRODUCT_DETAILS_INFO_SUCCESS;
import static com.guigu.gulicommon.constant.enumes.res.ServerResCode.UNKNOWN_EXCEPTION;

/**
 * <p>
 * sku信息 服务实现类
 * </p>
 *
 * @author 陈俊杰
 * @since 2024-07-13
 */
@Service
@Log4j2
public class SkuInfoServiceImpl extends ServiceImpl<SkuInfoMapper, SkuInfo> implements ISkuInfoService {
    @Autowired
    private SkuSaleAttrValueMapper skuSaleAttrValueMapper;
    @Autowired
    private ProductAttrValueMapper productAttrValueMapper;
    @Autowired
    private SpuInfoDescMapper spuInfoDescMapper;
    @Autowired
    private SkuInfoMapper skuInfoMapper;
    @Autowired
    private SkuImagesMapper skuImagesMapper;
    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    /**
     * 根据skuId查询商品详情
     *
     * @param skuId 商品skuId
     * @return 商品详情
     */
    @Override
    public Res<SkuInfoItemVo> getSkuInfoBySkuId(Long skuId) {
        SkuInfoItemVo skuInfoItemVo = new SkuInfoItemVo();

        CompletableFuture<SkuInfo> skuInfoFuture = CompletableFuture.supplyAsync(() -> {
            //1 获取 sku 基本信息->pms_sku_info
            SkuInfo skuInfo = skuInfoMapper.selectById(skuId);
            skuInfoItemVo.setSkuInfo(skuInfo);
            return skuInfo;
        }, threadPoolTaskExecutor);
        CompletableFuture<Void> skuItemSaleAttrFuture = skuInfoFuture.thenAcceptAsync(skuInfo -> {
            if (skuInfo != null) {
                //3 获取 spu 的销售属性组合信息->pms_sku_sale_attr_value
                List<SkuItemSaleAttrBo> skuItemSaleAttrBos = skuSaleAttrValueMapper.getSaleAttrsBySpuId(skuInfo.getSpuId());
                for (SkuItemSaleAttrBo skuItemSaleAttrBo : skuItemSaleAttrBos) {
                    //重新设置属性值为数组
                    skuItemSaleAttrBo.setAttrValueStrToAttrValueArr();
                }
                skuInfoItemVo.setSaleAttrs(skuItemSaleAttrBos);
            }
        });
        CompletableFuture<Void> spuInfoDescFuture = skuInfoFuture.thenAcceptAsync(skuInfo -> {
            //4 获取 spu 的描述信息->pms_spu_info_desc
            if (skuInfo.getSpuId() != null) {
                SpuInfoDesc spuInfoDesc = new LambdaQueryChainWrapper<>(spuInfoDescMapper).eq(SpuInfoDesc::getSpuId, skuInfo.getSpuId()).one();
                skuInfoItemVo.setSpuInfoDesc(spuInfoDesc);
            }
        });
        CompletableFuture<Void> spuItemAttrGroupFuture = skuInfoFuture.thenAcceptAsync(skuInfo -> {
            //5 获取 spu 的规格参数信息->pms_product_attr_value
            if (skuInfo.getSpuId() != null) {
                List<SpuItemAttrGroupBo> spuItemAttrGroupBos = productAttrValueMapper.getGroupWithAttrBySpuId(skuInfo.getSpuId(), skuInfo.getCatelogId());
                skuInfoItemVo.setGroupAttrs(spuItemAttrGroupBos);
            }
        });

        //2 获取 sku 的图片信息->pms_sku_images
        CompletableFuture<Void> skuImagesFuture = CompletableFuture.runAsync(() -> {
            List<SkuImages> skuImages = new LambdaQueryChainWrapper<>(skuImagesMapper).eq(SkuImages::getSkuId, skuId).list();
            skuInfoItemVo.setSkuImages(skuImages);
        }, threadPoolTaskExecutor);

        //等待所有任务完成
        try {
            CompletableFuture.allOf(skuItemSaleAttrFuture, spuInfoDescFuture, spuItemAttrGroupFuture, skuImagesFuture).get();
        } catch (InterruptedException | ExecutionException e) {
            log.error(e.getMessage());
            throw new BaseException(UNKNOWN_EXCEPTION);
        }

        return new Res<>(SELECT_PRODUCT_DETAILS_INFO_SUCCESS, skuInfoItemVo);
    }

    /**
     * 分页查询商品信息详情信息(通用)
     *
     * @param pagesDto 查询商品信息的参数
     * @return vo 商品信息详情的分页
     */
    @Override
    public Res<SkuInfoPageVo> findPages(SelectSkuInfoPagesDto pagesDto) {

        if (pagesDto.getPageNum() == null) {
            pagesDto.setPageNum(1L);
        }
        if (pagesDto.getPageSize() == null) {
            pagesDto.setPageSize(20L);
        }

        Page<SkuInfo> page = new LambdaQueryChainWrapper<>(baseMapper)
                .like(StringUtils.isNotBlank(pagesDto.getQueryParam()), SkuInfo::getSkuId, pagesDto.getQueryParam())
//                .or()
//                .like(StringUtils.isNotBlank(pagesDto.getQueryParam()), SkuInfo::getSpuId, pagesDto.getQueryParam())
//                .or()
//                .like(StringUtils.isNotBlank(pagesDto.getQueryParam()), SkuInfo::getCatelogId, pagesDto.getQueryParam())
//                .or()
//                .like(StringUtils.isNotBlank(pagesDto.getQueryParam()), SkuInfo::getBrandId, pagesDto.getQueryParam())
//                .or()
//                .like(StringUtils.isNotBlank(pagesDto.getQueryParam()), SkuInfo::getSkuDefaultImg, pagesDto.getQueryParam())
//                .or()
//                .like(StringUtils.isNotBlank(pagesDto.getQueryParam()), SkuInfo::getSkuTitle, pagesDto.getQueryParam())
//                .or()
//                .like(StringUtils.isNotBlank(pagesDto.getQueryParam()), SkuInfo::getSkuSubtitle, pagesDto.getQueryParam())
//                .or()
//                .like(StringUtils.isNotBlank(pagesDto.getQueryParam()), SkuInfo::getPrice, pagesDto.getQueryParam())
//                .or()
//                .like(StringUtils.isNotBlank(pagesDto.getQueryParam()), SkuInfo::getSaleCount, pagesDto.getQueryParam())
//                .or()
//                .like(StringUtils.isNotBlank(pagesDto.getQueryParam()), SkuInfo::getSkuName, pagesDto.getQueryParam())
//                .or()
//                .like(StringUtils.isNotBlank(pagesDto.getQueryParam()), SkuInfo::getSkuDesc, pagesDto.getQueryParam())
                .page(new Page<>(pagesDto.getPageNum(), pagesDto.getPageSize()));

        List<SkuInfoPageVo> infoPageVos = page.getRecords().stream().map(item -> {
            SkuInfoPageVo skuInfoPageVo = new SkuInfoPageVo();
            BeanUtils.copyProperties(item, skuInfoPageVo);
            return skuInfoPageVo;
        }).collect(Collectors.toList());
        PagePoJo<SkuInfoPageVo> skuInfoPageVoPagePoJo = new PagePoJo<>();
        skuInfoPageVoPagePoJo.setData(infoPageVos)
                .setPageNum(page.getCurrent())
                .setPageSize(page.getSize())
                .setRecords((long) page.getRecords().size())
                .setTotal(page.getTotal());
        return new Res<>(SELECT_PRODUCT_DETAILS_INFO_SUCCESS, skuInfoPageVoPagePoJo);
    }

    /**
     * 根据Id列表获取商品信息
     *
     * @param ids 商品id列表
     * @return 商品信息列表
     */
    @Override
    public Res<SkuInfoPageVo> getListByIds(List<Long> ids) {
        List<SkuInfoPageVo> vos = new LambdaQueryChainWrapper<>(baseMapper).in(SkuInfo::getSkuId, ids)
                .list()
                .stream().map(item -> {
                    SkuInfoPageVo skuInfoPageVo = new SkuInfoPageVo();
                    BeanUtils.copyProperties(item, skuInfoPageVo);
                    return skuInfoPageVo;
                }).collect(Collectors.toList());
        return new Res<>(SELECT_PRODUCT_DETAILS_INFO_SUCCESS, vos);
    }
}
